﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace TNCGameEngine.Content
{

    /// <summary>
    /// Defines a Loading Screen that can be displayed while contents a re loaded.
    /// </summary>
    public class LoadingScreen
    {

        #region "Properties"

        private Color backgroundcolor = Color.Black;
        /// <summary>
        /// The background color.
        /// </summary>
        /// <remarks>Gets or sets the color which is used to clear the buffer in the Draw method.</remarks>
        public Color BackgroundColor
        {
            get { return this.backgroundcolor; }
            set { this.backgroundcolor = value; }
        }

        /// <summary>
        /// Percentage of the total assets loaded.
        /// </summary>
        /// <remarks>Gets the percentage of the total assest to be loaded in the associated ContentLoader.</remarks>
        public float Percentage
        {
            get { return this.loader.Percentage; }
        }

        /// <summary>
        /// Graphics device associated with the content loader.
        /// </summary>
        /// <remarks>Gets the graphics device from the associated content loader.</remarks>
        public GraphicsDevice GraphicsDevice
        {
            get { return this.loader.GraphicsDevice; }
        }

        #endregion

        #region "Variables"

        private ContentLoader loader = null;
        private SpriteBatch spriteBatch = null;

        #endregion

        #region "Constructors"

        /// <summary>
        /// Generates a Loading Screen.
        /// </summary>
        public LoadingScreen(ContentLoader loader)
        {
            this.loader = loader;
            this.spriteBatch = new SpriteBatch(this.GraphicsDevice);
        }

        #endregion

        #region "Methods"

        /// <summary>
        /// Load all contents needed for displaying the LoadingScreen.
        /// </summary>
        /// <remarks>Loads nothing by default; may be overriden.</remarks>
        public virtual void LoadContent()
        {
            // do nothing
        }

        /// <summary>
        /// Unload all contents used for displaying the LoadingScreen.
        /// </summary>
        /// <remarks>Unloads nothing by default; may be overriden.</remarks>
        public virtual void UnloadContent()
        {
            // do nothing
        }

        /// <summary>
        /// The update method that may to be overriden to allow other displaying options.
        /// </summary>
        /// <param name="gameTime">The game time information.</param>
        public virtual void Update(GameTime gameTime)
        {

            if (!this.loader.IsLoading)
            {
                this.CheckAndContinue(gameTime);
            }

        }

        /// <summary>
        /// The draw method that may to be overriden to allow other displaying options.
        /// </summary>
        /// <param name="g">The graphics device associated with the current frame.</param>
        /// <remarks>Only clears the buffer using the BackgroundColor.</remarks>
        public virtual void Draw(GraphicsDevice g)
        {

            g.Clear(this.backgroundcolor);

            this.spriteBatch.Begin();

            string text = string.Empty;

            text = (this.loader.IsLoading) ? string.Format("Loading ({0:0} %)...", this.Percentage) : "Press any key to continue...";
            
            // TODO: set the font correctly
            //float w = this.loader.GeneralFont.MeasureString(text).X;
            //Viewport v = this.GraphicsDevice.Viewport;
            //this.spriteBatch.DrawString(this.loader.GeneralFont, text, new Vector2((v.Width - w) / 2.0f, v.Height / 2.0f), Color.White); 
            
            this.spriteBatch.End();

        }

        /// <summary>
        /// Checks for any user input to change to the next state.
        /// </summary>
        /// <param name="gameTime">The game time information.</param>
        /// <remarks>This method may be oveeriden to check for input (may be none) before returning to the next state.
        /// Use the ReturnToReturnState for transition.</remarks>
        public virtual void CheckAndContinue(GameTime gameTime)
        {

            KeyboardState keyboardState = Keyboard.GetState();

            if (keyboardState.GetPressedKeys().LongLength > 0)
            {
                this.ReturnToReturnState();
            }

        }

        /// <summary>
        /// Changes the current game state to the return state specified at the start of loading.
        /// </summary>
        protected void ReturnToReturnState()
        {
            this.loader.ReturnToReturnType();
        }

        #endregion

    }
}
